package part11singleton;

/**
 * @description: 线程安全的懒汉模式
 * 问题：
 * instance = new SingletonTest03(); 不是原子性操作，至少会经过三个步骤:
 * Step1：分配对象内存空间
 * Step2： 执行构造方法初始化对象
 * Steo3： 设置instance指向刚分配的内存地址，此时instance !=null;
 * 由于指令重排，导致A线程执行 lazyMan = new LazyMan();的时候，可能先执行了第三步(还没执行第 二步)，此时线程B又进来了，发现lazyMan已经不为空了，直接返回了lazyMan，并且后面使用了返回 的lazyMan，由于线程A还没有执行第二步，导致此时lazyMan还不完整，可能会有一些意想不到的错 误，所以就有了下面一种单例模式。
 * @author: zhang hang
 * @date: 2024/3/24 14:09.
 * @version: 1.0
 */
public class SingletonTest03 {

    private SingletonTest03() {
        System.out.println(Thread.currentThread().getName() + "starting");
    }

    private static SingletonTest03 instance;

    public static SingletonTest03 getInstance() {
        if (instance == null) {
            synchronized (SingletonTest03.class) {
                if (instance == null) {
                    instance = new SingletonTest03();
                }
            }
        }
        return instance;
    }

    // 并发场景下线程安全
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                SingletonTest03.getInstance();
            }).start();
        }
    }

}
